home *** CD-ROM | disk | FTP | other *** search
/ PC/CD Gamer UK 120 / CD Gamer Issue 120 (March 2003) (Disc 2).ISO / mods / Q2_Codered / codeRED1_0.exe / Data1.cab / r_surf.c < prev    next >
Encoding:
C/C++ Source or Header  |  2002-12-18  |  30.5 KB  |  1,396 lines

  1. /*
  2. Copyright (C) 1997-2001 Id Software, Inc.
  3.  
  4. This program is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU General Public License
  6. as published by the Free Software Foundation; either version 2
  7. of the License, or (at your option) any later version.
  8.  
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
  12.  
  13. See the GNU General Public License for more details.
  14.  
  15. You should have received a copy of the GNU General Public License
  16. along with this program; if not, write to the Free Software
  17. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  18.  
  19. */
  20. // R_SURF.C: surface-related refresh code
  21. #include <assert.h>
  22.  
  23. #include "r_local.h"
  24.  
  25. static vec3_t    modelorg;        // relative to viewpoint
  26.  
  27. msurface_t    *r_alpha_surfaces;
  28.  
  29. #define DYNAMIC_LIGHT_WIDTH  128
  30. #define DYNAMIC_LIGHT_HEIGHT 128
  31.  
  32. #define LIGHTMAP_BYTES 4
  33.  
  34. #define    BLOCK_WIDTH        128
  35. #define    BLOCK_HEIGHT    128
  36.  
  37. #define    MAX_LIGHTMAPS    128
  38.  
  39. int        c_visible_lightmaps;
  40. int        c_visible_textures;
  41.  
  42. #define GL_LIGHTMAP_FORMAT GL_RGBA
  43.  
  44. typedef struct
  45. {
  46.     int internal_format;
  47.     int    current_lightmap_texture;
  48.  
  49.     msurface_t    *lightmap_surfaces[MAX_LIGHTMAPS];
  50.  
  51.     int            allocated[BLOCK_WIDTH];
  52.  
  53.     // the lightmap texture data needs to be kept in
  54.     // main memory so texsubimage can update properly
  55.     byte        lightmap_buffer[4*BLOCK_WIDTH*BLOCK_HEIGHT];
  56. } gllightmapstate_t;
  57.  
  58. static gllightmapstate_t gl_lms;
  59.  
  60.  
  61. static void        LM_InitBlock( void );
  62. static void        LM_UploadBlock( qboolean dynamic );
  63. static qboolean    LM_AllocBlock (int w, int h, int *x, int *y);
  64.  
  65. extern void R_SetCacheState( msurface_t *surf );
  66. extern void R_BuildLightMap (msurface_t *surf, byte *dest, int stride);
  67.  
  68. /*
  69. =============================================================
  70.  
  71.     BRUSH MODELS
  72.  
  73. =============================================================
  74. */
  75.  
  76. /*
  77. ===============
  78. R_TextureAnimation
  79.  
  80. Returns the proper texture for a given time and base texture
  81. ===============
  82. */
  83. image_t *R_TextureAnimation (mtexinfo_t *tex)
  84. {
  85.     int        c;
  86.  
  87.     if (!tex->next)
  88.         return tex->image;
  89.  
  90.     c = currententity->frame % tex->numframes;
  91.     while (c)
  92.     {
  93.         tex = tex->next;
  94.         c--;
  95.     }
  96.  
  97.     return tex->image;
  98. }
  99.  
  100. /*
  101. ================
  102. DrawGLPoly
  103. ================
  104. */
  105. void DrawGLPoly (glpoly_t *p, int flags)
  106. {
  107.     int        i;
  108.     float    *v = p->verts[0];
  109.     float    scroll;
  110.  
  111.     scroll = 0;
  112.     if (flags & SURF_FLOWING)
  113.     {
  114.         scroll = -64 * ( (r_newrefdef.time / 40.0) - (int)(r_newrefdef.time / 40.0) );
  115.         if (scroll == 0.0)
  116.             scroll = -64.0;
  117.     }
  118.  
  119.     qglBegin (GL_POLYGON);
  120.     for (i=0 ; i<p->numverts ; i++, v+= VERTEXSIZE)
  121.     {
  122.         qglTexCoord2f (v[3] + scroll, v[4]);
  123.         qglVertex3fv (v);
  124.     }
  125.     qglEnd ();
  126. }
  127.  
  128. /*
  129. ** R_DrawTriangleOutlines
  130. */
  131. void R_DrawTriangleOutlines (void)
  132. {
  133.     int            i, j;
  134.     glpoly_t    *p;
  135.  
  136.     if (!gl_showtris->value)
  137.         return;
  138.  
  139.     qglDisable (GL_TEXTURE_2D);
  140.     qglDisable (GL_DEPTH_TEST);
  141.     qglColor4f (1,1,1,1);
  142.  
  143.     for (i=0 ; i<MAX_LIGHTMAPS ; i++)
  144.     {
  145.         msurface_t *surf;
  146.  
  147.         for ( surf = gl_lms.lightmap_surfaces[i]; surf != 0; surf = surf->lightmapchain )
  148.         {
  149.             p = surf->polys;
  150.             for (j=2 ; j<p->numverts ; j++ )
  151.             {
  152.                 qglBegin (GL_LINE_STRIP);
  153.                 qglVertex3fv (p->verts[0]);
  154.                 qglVertex3fv (p->verts[j-1]);
  155.                 qglVertex3fv (p->verts[j]);
  156.                 qglVertex3fv (p->verts[0]);
  157.                 qglEnd ();
  158.             }
  159.         }
  160.     }
  161.  
  162.     qglEnable (GL_DEPTH_TEST);
  163.     qglEnable (GL_TEXTURE_2D);
  164. }
  165.  
  166. /*
  167. ** DrawGLPolyLightmap
  168. */
  169. void DrawGLPolyLightmap( glpoly_t *p, float soffset, float toffset )
  170. {
  171.     float *v = p->verts[0];
  172.     int j;
  173.     
  174.     qglBegin (GL_POLYGON);
  175.     for (j=0 ; j<p->numverts ; j++, v+= VERTEXSIZE)
  176.     {
  177.         qglTexCoord2f (v[5] - soffset, v[6] - toffset );
  178.         qglVertex3fv (v);
  179.     }
  180.     qglEnd ();
  181. }
  182.  
  183. /*
  184. ** R_BlendLightMaps
  185. **
  186. ** This routine takes all the given light mapped surfaces in the world and
  187. ** blends them into the framebuffer.
  188. */
  189. void R_BlendLightmaps (void)
  190. {
  191.     int            i;
  192.     msurface_t    *surf, *newdrawsurf = 0;
  193.  
  194.     // don't bother if we're set to fullbright
  195.     if (r_fullbright->value)
  196.         return;
  197.     if (!r_worldmodel->lightdata)
  198.         return;
  199.  
  200.     // don't bother writing Z
  201.     qglDepthMask( 0 );
  202.  
  203.     /*
  204.     ** set the appropriate blending mode unless we're only looking at the
  205.     ** lightmaps.
  206.     */
  207.     if (!gl_lightmap->value)
  208.     {
  209.         qglEnable (GL_BLEND);
  210.  
  211.         if ( gl_saturatelighting->value )
  212.         {
  213.             qglBlendFunc( GL_ONE, GL_ONE );
  214.         }
  215.         else
  216.         {
  217.             if ( gl_monolightmap->string[0] != '0' )
  218.             {
  219.                 switch ( toupper( gl_monolightmap->string[0] ) )
  220.                 {
  221.                 case 'I':
  222.                     qglBlendFunc (GL_ZERO, GL_SRC_COLOR );
  223.                     break;
  224.                 case 'L':
  225.                     qglBlendFunc (GL_ZERO, GL_SRC_COLOR );
  226.                     break;
  227.                 case 'A':
  228.                 default:
  229.                     qglBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
  230.                     break;
  231.                 }
  232.             }
  233.             else
  234.             {
  235.                 qglBlendFunc (GL_ZERO, GL_SRC_COLOR );
  236.             }
  237.         }
  238.     }
  239.  
  240.     if ( currentmodel == r_worldmodel )
  241.         c_visible_lightmaps = 0;
  242.  
  243.     /*
  244.     ** render static lightmaps first
  245.     */
  246.     for ( i = 1; i < MAX_LIGHTMAPS; i++ )
  247.     {
  248.         if ( gl_lms.lightmap_surfaces[i] )
  249.         {
  250.             if (currentmodel == r_worldmodel)
  251.                 c_visible_lightmaps++;
  252.             GL_Bind( gl_state.lightmap_textures + i);
  253.  
  254.             for ( surf = gl_lms.lightmap_surfaces[i]; surf != 0; surf = surf->lightmapchain )
  255.             {
  256.                 if ( surf->polys )
  257.                     DrawGLPolyLightmap( surf->polys, 0, 0 );
  258.             }
  259.         }
  260.     }
  261.  
  262.     /*
  263.     ** render dynamic lightmaps
  264.     */
  265.     if ( gl_dynamic->value )
  266.     {
  267.         LM_InitBlock();
  268.  
  269.         GL_Bind( gl_state.lightmap_textures+0 );
  270.  
  271.         if (currentmodel == r_worldmodel)
  272.             c_visible_lightmaps++;
  273.  
  274.         newdrawsurf = gl_lms.lightmap_surfaces[0];
  275.  
  276.         for ( surf = gl_lms.lightmap_surfaces[0]; surf != 0; surf = surf->lightmapchain )
  277.         {
  278.             int        smax, tmax;
  279.             byte    *base;
  280.  
  281.             smax = (surf->extents[0]>>4)+1;
  282.             tmax = (surf->extents[1]>>4)+1;
  283.  
  284.             if ( LM_AllocBlock( smax, tmax, &surf->dlight_s, &surf->dlight_t ) )
  285.             {
  286.                 base = gl_lms.lightmap_buffer;
  287.                 base += ( surf->dlight_t * BLOCK_WIDTH + surf->dlight_s ) * LIGHTMAP_BYTES;
  288.  
  289.                 R_BuildLightMap (surf, base, BLOCK_WIDTH*LIGHTMAP_BYTES);
  290.             }
  291.             else
  292.             {
  293.                 msurface_t *drawsurf;
  294.  
  295.                 // upload what we have so far
  296.                 LM_UploadBlock( true );
  297.  
  298.                 // draw all surfaces that use this lightmap
  299.                 for ( drawsurf = newdrawsurf; drawsurf != surf; drawsurf = drawsurf->lightmapchain )
  300.                 {
  301.                     if ( drawsurf->polys )
  302.                         DrawGLPolyLightmap( drawsurf->polys, 
  303.                                           ( drawsurf->light_s - drawsurf->dlight_s ) * ( 1.0 / 128.0 ), 
  304.                                         ( drawsurf->light_t - drawsurf->dlight_t ) * ( 1.0 / 128.0 ) );
  305.                 }
  306.  
  307.                 newdrawsurf = drawsurf;
  308.  
  309.                 // clear the block
  310.                 LM_InitBlock();
  311.  
  312.                 // try uploading the block now
  313.                 if ( !LM_AllocBlock( smax, tmax, &surf->dlight_s, &surf->dlight_t ) )
  314.                 {
  315.                     Com_Error( ERR_FATAL, "Consecutive calls to LM_AllocBlock(%d,%d) failed (dynamic)\n", smax, tmax );
  316.                 }
  317.  
  318.                 base = gl_lms.lightmap_buffer;
  319.                 base += ( surf->dlight_t * BLOCK_WIDTH + surf->dlight_s ) * LIGHTMAP_BYTES;
  320.  
  321.                 R_BuildLightMap (surf, base, BLOCK_WIDTH*LIGHTMAP_BYTES);
  322.             }
  323.         }
  324.  
  325.         /*
  326.         ** draw remainder of dynamic lightmaps that haven't been uploaded yet
  327.         */
  328.         if ( newdrawsurf )
  329.             LM_UploadBlock( true );
  330.  
  331.         for ( surf = newdrawsurf; surf != 0; surf = surf->lightmapchain )
  332.         {
  333.             if ( surf->polys )
  334.                 DrawGLPolyLightmap( surf->polys, ( surf->light_s - surf->dlight_s ) * ( 1.0 / 128.0 ), ( surf->light_t - surf->dlight_t ) * ( 1.0 / 128.0 ) );
  335.         }
  336.     }
  337.  
  338.     /*
  339.     ** restore state
  340.     */
  341.     qglDisable (GL_BLEND);
  342.     qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  343.     qglDepthMask( 1 );
  344. }
  345.  
  346. /*
  347. ================
  348. R_RenderBrushPoly
  349. ================
  350. */
  351. void R_RenderBrushPoly (msurface_t *fa)
  352. {
  353.     int            maps;
  354.     image_t        *image;
  355.     qboolean is_dynamic = false;
  356.  
  357.     c_brush_polys++;
  358.  
  359.     image = R_TextureAnimation (fa->texinfo);
  360.  
  361.     if (fa->flags & SURF_DRAWTURB)
  362.     {    
  363.         GL_Bind( image->texnum );
  364.  
  365.         // warp texture, no lightmaps
  366.         GL_TexEnv( GL_MODULATE );
  367.         qglColor4f( gl_state.inverse_intensity, 
  368.                     gl_state.inverse_intensity,
  369.                     gl_state.inverse_intensity,
  370.                     1.0F );
  371.         EmitWaterPolys (fa);
  372.         GL_TexEnv( GL_REPLACE );
  373.  
  374.         return;
  375.     }
  376.     else
  377.     {
  378.         GL_Bind( image->texnum );
  379.  
  380.         GL_TexEnv( GL_REPLACE );
  381.     }
  382.  
  383.     if (SurfaceIsAlphaBlended(fa))
  384.         qglEnable( GL_ALPHA_TEST );
  385.     
  386.     DrawGLPoly (fa->polys, fa->texinfo->flags);
  387.  
  388.     if (SurfaceIsAlphaBlended(fa))
  389.     {
  390.         qglDisable( GL_ALPHA_TEST );
  391.         return;
  392.     }//for now until Vic fixes problems with colored lightmaps on these surfaces
  393.  
  394.     /*
  395.     ** check for lightmap modification
  396.     */
  397.     for ( maps = 0; maps < MAXLIGHTMAPS && fa->styles[maps] != 255; maps++ )
  398.     {
  399.         if ( r_newrefdef.lightstyles[fa->styles[maps]].white != fa->cached_light[maps] )
  400.             goto dynamic;
  401.     }
  402.  
  403.     // dynamic this frame or dynamic previously
  404.     if ( ( fa->dlightframe == r_framecount ) )
  405.     {
  406. dynamic:
  407.         if ( gl_dynamic->value )
  408.         {
  409.             if ( !SurfaceHasNoLightmap( fa ) )
  410.             {
  411.                 is_dynamic = true;
  412.             }
  413.         }
  414.     }
  415.  
  416.     if ( is_dynamic )
  417.     {
  418.         if ( ( fa->styles[maps] >= 32 || fa->styles[maps] == 0 ) && ( fa->dlightframe != r_framecount ) )
  419.         {
  420.             unsigned    temp[34*34];
  421.             int            smax, tmax;
  422.  
  423.             smax = (fa->extents[0]>>4)+1;
  424.             tmax = (fa->extents[1]>>4)+1;
  425.  
  426.             R_BuildLightMap( fa, (void *)temp, smax*4 );
  427.             R_SetCacheState( fa );
  428.  
  429.             GL_Bind( gl_state.lightmap_textures + fa->lightmaptexturenum );
  430.  
  431.             qglTexSubImage2D( GL_TEXTURE_2D, 0,
  432.                               fa->light_s, fa->light_t, 
  433.                               smax, tmax, 
  434.                               GL_LIGHTMAP_FORMAT, 
  435.                               GL_UNSIGNED_BYTE, temp );
  436.  
  437.             fa->lightmapchain = gl_lms.lightmap_surfaces[fa->lightmaptexturenum];
  438.             gl_lms.lightmap_surfaces[fa->lightmaptexturenum] = fa;
  439.         }
  440.         else
  441.         {
  442.             fa->lightmapchain = gl_lms.lightmap_surfaces[0];
  443.             gl_lms.lightmap_surfaces[0] = fa;
  444.         }
  445.     }
  446.     else
  447.     {
  448.         fa->lightmapchain = gl_lms.lightmap_surfaces[fa->lightmaptexturenum];
  449.         gl_lms.lightmap_surfaces[fa->lightmaptexturenum] = fa;
  450.     }
  451. }
  452.  
  453.  
  454. /*
  455. ================
  456. R_DrawAlphaSurfaces
  457.  
  458. Draw water surfaces and windows.
  459. The BSP tree is waled front to back, so unwinding the chain
  460. of alpha_surfaces will draw back to front, giving proper ordering.
  461. ================
  462. */
  463. void R_DrawAlphaSurfaces (void)
  464. {
  465.     msurface_t    *s;
  466.     float        intens;
  467.  
  468.     //
  469.     // go back to the world matrix
  470.     //
  471.     qglLoadMatrixf (r_world_matrix);
  472.  
  473.     qglDepthMask ( GL_FALSE );
  474.     qglEnable (GL_BLEND);
  475.     GL_TexEnv( GL_MODULATE );
  476.  
  477.     // the textures are prescaled up for a better lighting range,
  478.     // so scale it back down
  479.     intens = gl_state.inverse_intensity;
  480.  
  481.     for (s=r_alpha_surfaces ; s ; s=s->texturechain)
  482.     {
  483.         GL_Bind(s->texinfo->image->texnum);
  484.         c_brush_polys++;
  485.  
  486.         if (s->texinfo->flags & SURF_TRANS33)
  487.             qglColor4f (intens, intens, intens, 0.33);
  488.         else if (s->texinfo->flags & SURF_TRANS66)
  489.             qglColor4f (intens, intens, intens, 0.66);
  490.         else
  491.             qglColor4f (intens, intens, intens, 1);
  492.  
  493.         if (s->flags & SURF_DRAWTURB)
  494.             EmitWaterPolys (s);
  495.         else
  496.             DrawGLPoly (s->polys, s->texinfo->flags);
  497.     }
  498.  
  499.     GL_TexEnv( GL_REPLACE );
  500.     qglColor4f (1,1,1,1);
  501.     qglDisable (GL_BLEND);
  502.     qglDepthMask ( GL_TRUE );
  503.  
  504.     r_alpha_surfaces = NULL;
  505. }
  506.  
  507. /*
  508. ================
  509. DrawTextureChains
  510. ================
  511. */
  512. void DrawTextureChains (void)
  513. {
  514.     int        i;
  515.     msurface_t    *s;
  516.     image_t        *image;
  517.  
  518.     c_visible_textures = 0;
  519.  
  520. //    GL_TexEnv( GL_REPLACE );
  521.  
  522.     if ( !qglSelectTextureSGIS && !qglActiveTextureARB )
  523.     {
  524.         for ( i = 0, image=gltextures ; i<numgltextures ; i++,image++)
  525.         {
  526.             if (!image->registration_sequence)
  527.                 continue;
  528.             s = image->texturechain;
  529.             if (!s)
  530.                 continue;
  531.             c_visible_textures++;
  532.  
  533.             for ( ; s ; s=s->texturechain)
  534.                 R_RenderBrushPoly (s);
  535.  
  536.             image->texturechain = NULL;
  537.         }
  538.     }
  539.     else
  540.     {
  541.         for ( i = 0, image=gltextures ; i<numgltextures ; i++,image++)
  542.         {
  543.             if (!image->registration_sequence)
  544.                 continue;
  545.             if (!image->texturechain)
  546.                 continue;
  547.             c_visible_textures++;
  548.  
  549.             for ( s = image->texturechain; s ; s=s->texturechain)
  550.             {
  551.                 if ( !( s->flags & SURF_DRAWTURB ) )
  552.                     R_RenderBrushPoly (s);
  553.             }
  554.         }
  555.  
  556.         GL_EnableMultitexture( false );
  557.         for ( i = 0, image=gltextures ; i<numgltextures ; i++,image++)
  558.         {
  559.             if (!image->registration_sequence)
  560.                 continue;
  561.             s = image->texturechain;
  562.             if (!s)
  563.                 continue;
  564.  
  565.             for ( ; s ; s=s->texturechain)
  566.             {
  567.                 if ( s->flags & SURF_DRAWTURB )
  568.                     R_RenderBrushPoly (s);
  569.             }
  570.  
  571.             image->texturechain = NULL;
  572.         }
  573. //        GL_EnableMultitexture( true );
  574.     }
  575.  
  576.     GL_TexEnv( GL_REPLACE );
  577. }
  578.  
  579.  
  580. static void GL_RenderLightmappedPoly( msurface_t *surf )
  581. {
  582.     int        i, nv = surf->polys->numverts;
  583.     int        map;
  584.     float    scroll;
  585.     float    *v;
  586.     image_t *image = R_TextureAnimation( surf->texinfo );
  587.     qboolean is_dynamic = false;
  588.     unsigned lmtex = surf->lightmaptexturenum;
  589.  
  590.     for ( map = 0; map < MAXLIGHTMAPS && surf->styles[map] != 255; map++ )
  591.     {
  592.         if ( r_newrefdef.lightstyles[surf->styles[map]].white != surf->cached_light[map] )
  593.             goto dynamic;
  594.     }
  595.  
  596.     // dynamic this frame or dynamic previously
  597.     if ( ( surf->dlightframe == r_framecount ) )
  598.     {
  599. dynamic:
  600.         if ( gl_dynamic->value )
  601.         {
  602.             if ( !SurfaceHasNoLightmap(surf) )
  603.                 is_dynamic = true;
  604.         }
  605.     }
  606.  
  607.     c_brush_polys++;
  608.  
  609.     if ( is_dynamic )
  610.     {
  611.         unsigned    temp[128*128];
  612.         int            smax, tmax;
  613.  
  614.         smax = (surf->extents[0]>>4)+1;
  615.         tmax = (surf->extents[1]>>4)+1;
  616.         
  617.         R_BuildLightMap( surf, (void *)temp, smax*4 );
  618.         
  619.         if ( ( surf->styles[map] >= 32 || surf->styles[map] == 0 ) && ( surf->dlightframe != r_framecount ) ) {
  620.             R_SetCacheState( surf );
  621.         } else {
  622.             lmtex = 0;
  623.         }
  624.  
  625.         GL_MBind( GL_TEXTURE1, gl_state.lightmap_textures + lmtex );
  626.         qglTexSubImage2D( GL_TEXTURE_2D, 0,
  627.                           surf->light_s, surf->light_t, 
  628.                           smax, tmax, 
  629.                           GL_LIGHTMAP_FORMAT, 
  630.                           GL_UNSIGNED_BYTE, temp );
  631.     }
  632.  
  633.     if (SurfaceIsAlphaBlended(surf))
  634.         qglEnable( GL_ALPHA_TEST );
  635.  
  636.     GL_MBind( GL_TEXTURE0, image->texnum );
  637.     GL_MBind( GL_TEXTURE1, gl_state.lightmap_textures + lmtex );
  638.  
  639.     scroll = 0;
  640.     if (surf->texinfo->flags & SURF_FLOWING)
  641.     {
  642.         scroll = -64 * ( (r_newrefdef.time / 40.0) - (int)(r_newrefdef.time / 40.0) );
  643.         if (scroll == 0.0)
  644.             scroll = -64.0;
  645.     }
  646.  
  647.     v = surf->polys->verts[0];
  648.     qglBegin (GL_POLYGON);
  649.     for (i=0 ; i< nv; i++, v+= VERTEXSIZE)
  650.     {
  651.         qglMTexCoord2fSGIS( GL_TEXTURE0, v[3]+scroll, v[4]);
  652.         qglMTexCoord2fSGIS( GL_TEXTURE1, v[5], v[6]);
  653.         qglVertex3fv (v);
  654.     }
  655.     qglEnd ();
  656.  
  657.     if (SurfaceIsAlphaBlended(surf))
  658.         qglDisable( GL_ALPHA_TEST);
  659. }
  660.  
  661. /*
  662. =================
  663. R_DrawInlineBModel
  664. =================
  665. */
  666. void R_DrawInlineBModel (void)
  667. {
  668.     int            i;
  669.     cplane_t    *pplane;
  670.     float        dot;
  671.     msurface_t    *psurf;
  672.  
  673.     R_PushDlightsForBModel ( currententity );
  674.  
  675.     if ( currententity->flags & RF_TRANSLUCENT )
  676.     {
  677.         qglEnable (GL_BLEND);
  678.         qglColor4f (1,1,1,0.25);
  679.         GL_TexEnv( GL_MODULATE );
  680.     }
  681.  
  682.     //
  683.     // draw texture
  684.     //
  685.     psurf = ¤tmodel->surfaces[currentmodel->firstmodelsurface];
  686.     for (i=0 ; i<currentmodel->nummodelsurfaces ; i++, psurf++)
  687.     {
  688.     // find which side of the plane we are on
  689.         pplane = psurf->plane;
  690.         dot = DotProduct (modelorg, pplane->normal) - pplane->dist;
  691.  
  692.     // draw the polygon
  693.         if (((psurf->flags & SURF_PLANEBACK) && (dot < -BACKFACE_EPSILON)) ||
  694.             (!(psurf->flags & SURF_PLANEBACK) && (dot > BACKFACE_EPSILON)))
  695.         {
  696.             if (SurfaceIsTranslucent(psurf) && !SurfaceIsAlphaBlended(psurf))
  697.             {    // add to the translucent chain
  698.                 psurf->texturechain = r_alpha_surfaces;
  699.                 r_alpha_surfaces = psurf;
  700.             }
  701.             else if ( qglMTexCoord2fSGIS && !( psurf->flags & SURF_DRAWTURB ) )
  702.             {
  703.                 GL_RenderLightmappedPoly( psurf );
  704.             }
  705.             else
  706.             {
  707.                 GL_EnableMultitexture( false );
  708.                 R_RenderBrushPoly( psurf );
  709.                 GL_EnableMultitexture( true );
  710.             }
  711.  
  712.             psurf->visframe = r_framecount;
  713.         }
  714.     }
  715.  
  716.     if ( !(currententity->flags & RF_TRANSLUCENT) )
  717.     {
  718.         if ( !qglMTexCoord2fSGIS )
  719.             R_BlendLightmaps ();
  720.     }
  721.     else
  722.     {
  723.         qglDisable (GL_BLEND);
  724.         qglColor4f (1,1,1,1);
  725.         GL_TexEnv( GL_REPLACE );
  726.     }
  727. }
  728.  
  729. /*
  730. =================
  731. R_DrawBrushModel
  732. =================
  733. */
  734. void R_DrawBrushModel (entity_t *e)
  735. {
  736.     vec3_t        mins, maxs;
  737.     int            i;
  738.     qboolean    rotated;
  739.  
  740.     if (currentmodel->nummodelsurfaces == 0)
  741.         return;
  742.  
  743.     currententity = e;
  744.     gl_state.currenttextures[0] = gl_state.currenttextures[1] = -1;
  745.  
  746.     if (e->angles[0] || e->angles[1] || e->angles[2])
  747.     {
  748.         rotated = true;
  749.         for (i=0 ; i<3 ; i++)
  750.         {
  751.             mins[i] = e->origin[i] - currentmodel->radius;
  752.             maxs[i] = e->origin[i] + currentmodel->radius;
  753.         }
  754.     }
  755.     else
  756.     {
  757.         rotated = false;
  758.         VectorAdd (e->origin, currentmodel->mins, mins);
  759.         VectorAdd (e->origin, currentmodel->maxs, maxs);
  760.     }
  761.  
  762.     R_PushStainsForBModel ( e );
  763.  
  764.     if (R_CullBox (mins, maxs)) {
  765.         return;
  766.     }
  767.  
  768.     qglColor3f (1,1,1);
  769.     memset (gl_lms.lightmap_surfaces, 0, sizeof(gl_lms.lightmap_surfaces));
  770.  
  771.     VectorSubtract (r_newrefdef.vieworg, e->origin, modelorg);
  772.     if (rotated)
  773.     {
  774.         vec3_t    temp;
  775.         vec3_t    forward, right, up;
  776.  
  777.         VectorCopy (modelorg, temp);
  778.         AngleVectors (e->angles, forward, right, up);
  779.         modelorg[0] = DotProduct (temp, forward);
  780.         modelorg[1] = -DotProduct (temp, right);
  781.         modelorg[2] = DotProduct (temp, up);
  782.     }
  783.  
  784.     qglPushMatrix ();
  785. e->angles[0] = -e->angles[0];    // stupid quake bug
  786. e->angles[2] = -e->angles[2];    // stupid quake bug
  787.     R_RotateForEntity (e);
  788. e->angles[0] = -e->angles[0];    // stupid quake bug
  789. e->angles[2] = -e->angles[2];    // stupid quake bug
  790.  
  791.     GL_EnableMultitexture( true );
  792.     GL_SelectTexture( GL_TEXTURE0);
  793.     GL_TexEnv( GL_REPLACE );
  794.     GL_SelectTexture( GL_TEXTURE1);
  795.     GL_TexEnv( GL_MODULATE );
  796.  
  797.     R_DrawInlineBModel ();
  798.     GL_EnableMultitexture( false );
  799.  
  800.     qglPopMatrix ();
  801. }
  802.  
  803. /*
  804. =============================================================
  805.  
  806.     WORLD MODEL
  807.  
  808. =============================================================
  809. */
  810.  
  811. /*
  812. ================
  813. R_RecursiveWorldNode
  814. ================
  815. */
  816. void R_RecursiveWorldNode (mnode_t *node)
  817. {
  818.     int            c, side, sidebit;
  819.     cplane_t    *plane;
  820.     msurface_t    *surf, **mark;
  821.     mleaf_t        *pleaf;
  822.     float        dot;
  823.     image_t        *image;
  824.  
  825.     if (node->contents == CONTENTS_SOLID)
  826.         return;        // solid
  827.  
  828.     if (node->visframe != r_visframecount)
  829.         return;
  830.     if (R_CullBox (node->minmaxs, node->minmaxs+3))
  831.         return;
  832.     
  833. // if a leaf node, draw stuff
  834.     if (node->contents != -1)
  835.     {
  836.         pleaf = (mleaf_t *)node;
  837.  
  838.         // check for door connected areas
  839.         if (r_newrefdef.areabits)
  840.         {
  841.             if (! (r_newrefdef.areabits[pleaf->area>>3] & (1<<(pleaf->area&7)) ) )
  842.                 return;        // not visible
  843.         }
  844.  
  845.         mark = pleaf->firstmarksurface;
  846.         if (! (c = pleaf->nummarksurfaces) )
  847.             return;
  848.  
  849.         do
  850.         {
  851.             (*mark++)->visframe = r_framecount;
  852.         } while (--c);
  853.  
  854.         return;
  855.     }
  856.  
  857. // node is just a decision point, so go down the apropriate sides
  858.  
  859. // find which side of the node we are on
  860.     plane = node->plane;
  861.  
  862.     switch (plane->type)
  863.     {
  864.     case PLANE_X:
  865.         dot = modelorg[0] - plane->dist;
  866.         break;
  867.     case PLANE_Y:
  868.         dot = modelorg[1] - plane->dist;
  869.         break;
  870.     case PLANE_Z:
  871.         dot = modelorg[2] - plane->dist;
  872.         break;
  873.     default:
  874.         dot = DotProduct (modelorg, plane->normal) - plane->dist;
  875.         break;
  876.     }
  877.  
  878.     if (dot >= 0)
  879.     {
  880.         side = 0;
  881.         sidebit = 0;
  882.     }
  883.     else
  884.     {
  885.         side = 1;
  886.         sidebit = SURF_PLANEBACK;
  887.     }
  888.  
  889. // recurse down the children, front side first
  890.     R_RecursiveWorldNode (node->children[side]);
  891.  
  892.     // draw stuff
  893.     for ( c = node->numsurfaces, surf = r_worldmodel->surfaces + node->firstsurface; c ; c--, surf++)
  894.     {
  895.         if (surf->visframe != r_framecount)
  896.             continue;
  897.  
  898.         if ( (surf->flags & SURF_PLANEBACK) != sidebit )
  899.             continue;        // wrong side
  900.         if (surf->texinfo->flags & SURF_SKY)
  901.         {    // just adds to visible sky bounds
  902.             R_AddSkySurface (surf);
  903.         }
  904.         else if (SurfaceIsTranslucent(surf) && !SurfaceIsAlphaBlended(surf))
  905.         {    // add to the translucent chain
  906.             surf->texturechain = r_alpha_surfaces;
  907.             r_alpha_surfaces = surf;
  908.         }
  909.         else
  910.         {
  911.             if ( qglMTexCoord2fSGIS && !( surf->flags & SURF_DRAWTURB ) )
  912.             {
  913.                 GL_RenderLightmappedPoly( surf );
  914.             }
  915.             else
  916.             {
  917.                 // the polygon is visible, so add it to the texture
  918.                 // sorted chain
  919.                 // FIXME: this is a hack for animation
  920.                 image = R_TextureAnimation (surf->texinfo);
  921.                 surf->texturechain = image->texturechain;
  922.                 image->texturechain = surf;
  923.             }
  924.         }
  925.     }
  926.  
  927.     // recurse down the back side
  928.     R_RecursiveWorldNode (node->children[!side]);
  929. }
  930.  
  931.  
  932. /*
  933. =============
  934. R_DrawWorld
  935. =============
  936. */
  937. void R_DrawWorld (void)
  938. {
  939.     entity_t    ent;
  940.  
  941.     if (!r_drawworld->value)
  942.         return;
  943.  
  944.     if ( r_newrefdef.rdflags & RDF_NOWORLDMODEL )
  945.         return;
  946.  
  947.     currentmodel = r_worldmodel;
  948.  
  949.     VectorCopy (r_newrefdef.vieworg, modelorg);
  950.  
  951.     // auto cycle the world frame for texture animation
  952.     memset (&ent, 0, sizeof(ent));
  953.     ent.frame = (int)(r_newrefdef.time*2);
  954.     currententity = &ent;
  955.  
  956.     gl_state.currenttextures[0] = gl_state.currenttextures[1] = -1;
  957.  
  958.     qglColor3f (1,1,1);
  959.     memset (gl_lms.lightmap_surfaces, 0, sizeof(gl_lms.lightmap_surfaces));
  960.  
  961.     R_ClearSkyBox ();
  962.  
  963.     if ( qglMTexCoord2fSGIS )
  964.     {
  965.         GL_EnableMultitexture( true );
  966.  
  967.         GL_SelectTexture( GL_TEXTURE0);
  968.         GL_TexEnv( GL_REPLACE );
  969.         GL_SelectTexture( GL_TEXTURE1);
  970.  
  971.         if ( gl_lightmap->value )
  972.             GL_TexEnv( GL_REPLACE );
  973.         else 
  974.             GL_TexEnv( GL_MODULATE );
  975.  
  976.         R_RecursiveWorldNode (r_worldmodel->nodes);
  977.  
  978.         GL_EnableMultitexture( false );
  979.     }
  980.     else
  981.     {
  982.         R_RecursiveWorldNode (r_worldmodel->nodes);
  983.     }
  984.  
  985.     /*
  986.     ** theoretically nothing should happen in the next two functions
  987.     ** if multitexture is enabled
  988.     */
  989.     DrawTextureChains ();
  990.     R_BlendLightmaps ();
  991.  
  992.     R_DrawSkyBox ();
  993.  
  994.     R_DrawTriangleOutlines ();
  995. }
  996.  
  997.  
  998. /*
  999. ===============
  1000. R_MarkLeaves
  1001.  
  1002. Mark the leaves and nodes that are in the PVS for the current
  1003. cluster
  1004. ===============
  1005. */
  1006. void R_MarkLeaves (void)
  1007. {
  1008.     byte    *vis;
  1009.     byte    fatvis[MAX_MAP_LEAFS/8];
  1010.     mnode_t    *node;
  1011.     int        i, c;
  1012.     mleaf_t    *leaf;
  1013.     int        cluster;
  1014.  
  1015.     if (r_oldviewcluster == r_viewcluster && r_oldviewcluster2 == r_viewcluster2 && !r_novis->value && r_viewcluster != -1)
  1016.         return;
  1017.  
  1018.     // development aid to let you run around and see exactly where
  1019.     // the pvs ends
  1020.     if (gl_lockpvs->value)
  1021.         return;
  1022.  
  1023.     r_visframecount++;
  1024.     r_oldviewcluster = r_viewcluster;
  1025.     r_oldviewcluster2 = r_viewcluster2;
  1026.  
  1027.     if (r_novis->value || r_viewcluster == -1 || !r_worldmodel->vis)
  1028.     {
  1029.         // mark everything
  1030.         for (i=0 ; i<r_worldmodel->numleafs ; i++)
  1031.             r_worldmodel->leafs[i].visframe = r_visframecount;
  1032.         for (i=0 ; i<r_worldmodel->numnodes ; i++)
  1033.             r_worldmodel->nodes[i].visframe = r_visframecount;
  1034.         return;
  1035.     }
  1036.  
  1037.     vis = Mod_ClusterPVS (r_viewcluster, r_worldmodel);
  1038.     // may have to combine two clusters because of solid water boundaries
  1039.     if (r_viewcluster2 != r_viewcluster)
  1040.     {
  1041.         memcpy (fatvis, vis, (r_worldmodel->numleafs+7)/8);
  1042.         vis = Mod_ClusterPVS (r_viewcluster2, r_worldmodel);
  1043.         c = (r_worldmodel->numleafs+31)/32;
  1044.         for (i=0 ; i<c ; i++)
  1045.             ((int *)fatvis)[i] |= ((int *)vis)[i];
  1046.         vis = fatvis;
  1047.     }
  1048.     
  1049.     for (i=0,leaf=r_worldmodel->leafs ; i<r_worldmodel->numleafs ; i++, leaf++)
  1050.     {
  1051.         cluster = leaf->cluster;
  1052.         if (cluster == -1)
  1053.             continue;
  1054.         if (vis[cluster>>3] & (1<<(cluster&7)))
  1055.         {
  1056.             node = (mnode_t *)leaf;
  1057.             do
  1058.             {
  1059.                 if (node->visframe == r_visframecount)
  1060.                     break;
  1061.                 node->visframe = r_visframecount;
  1062.                 node = node->parent;
  1063.             } while (node);
  1064.         }
  1065.     }
  1066. }
  1067.  
  1068.  
  1069.  
  1070. /*
  1071. =============================================================================
  1072.  
  1073.   LIGHTMAP ALLOCATION
  1074.  
  1075. =============================================================================
  1076. */
  1077.  
  1078. static void LM_InitBlock( void )
  1079. {
  1080.     memset( gl_lms.allocated, 0, sizeof( gl_lms.allocated ) );
  1081. }
  1082.  
  1083. static void LM_UploadBlock( qboolean dynamic )
  1084. {
  1085.     int texture;
  1086.     int height = 0;
  1087.  
  1088.     if ( dynamic )
  1089.     {
  1090.         texture = 0;
  1091.     }
  1092.     else
  1093.     {
  1094.         texture = gl_lms.current_lightmap_texture;
  1095.     }
  1096.  
  1097.     GL_Bind( gl_state.lightmap_textures + texture );
  1098.     qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  1099.     qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  1100.  
  1101.     if ( dynamic )
  1102.     {
  1103.         int i;
  1104.  
  1105.         for ( i = 0; i < BLOCK_WIDTH; i++ )
  1106.         {
  1107.             if ( gl_lms.allocated[i] > height )
  1108.                 height = gl_lms.allocated[i];
  1109.         }
  1110.  
  1111.         qglTexSubImage2D( GL_TEXTURE_2D, 
  1112.                           0,
  1113.                           0, 0,
  1114.                           BLOCK_WIDTH, height,
  1115.                           GL_LIGHTMAP_FORMAT,
  1116.                           GL_UNSIGNED_BYTE,
  1117.                           gl_lms.lightmap_buffer );
  1118.     }
  1119.     else
  1120.     {
  1121.         qglTexImage2D( GL_TEXTURE_2D, 
  1122.                        0, 
  1123.                        gl_lms.internal_format,
  1124.                        BLOCK_WIDTH, BLOCK_HEIGHT, 
  1125.                        0, 
  1126.                        GL_LIGHTMAP_FORMAT, 
  1127.                        GL_UNSIGNED_BYTE, 
  1128.                        gl_lms.lightmap_buffer );
  1129.         if ( ++gl_lms.current_lightmap_texture == MAX_LIGHTMAPS )
  1130.             Com_Error( ERR_DROP, "LM_UploadBlock() - MAX_LIGHTMAPS exceeded\n" );
  1131.     }
  1132. }
  1133.  
  1134. // returns a texture number and the position inside it
  1135. static qboolean LM_AllocBlock (int w, int h, int *x, int *y)
  1136. {
  1137.     int        i, j;
  1138.     int        best, best2;
  1139.  
  1140.     best = BLOCK_HEIGHT;
  1141.  
  1142.     for (i=0 ; i<BLOCK_WIDTH-w ; i++)
  1143.     {
  1144.         best2 = 0;
  1145.  
  1146.         for (j=0 ; j<w ; j++)
  1147.         {
  1148.             if (gl_lms.allocated[i+j] >= best)
  1149.                 break;
  1150.             if (gl_lms.allocated[i+j] > best2)
  1151.                 best2 = gl_lms.allocated[i+j];
  1152.         }
  1153.         if (j == w)
  1154.         {    // this is a valid spot
  1155.             *x = i;
  1156.             *y = best = best2;
  1157.         }
  1158.     }
  1159.  
  1160.     if (best + h > BLOCK_HEIGHT)
  1161.         return false;
  1162.  
  1163.     for (i=0 ; i<w ; i++)
  1164.         gl_lms.allocated[*x + i] = best + h;
  1165.  
  1166.     return true;
  1167. }
  1168.  
  1169. /*
  1170. ================
  1171. GL_BuildPolygonFromSurface
  1172. ================
  1173. */
  1174. void GL_BuildPolygonFromSurface(msurface_t *fa)
  1175. {
  1176.     int            i, lindex, lnumverts;
  1177.     medge_t        *r_pedge;
  1178.     float        *vec;
  1179.     float        s, t;
  1180.     glpoly_t    *poly;
  1181.  
  1182. // reconstruct the polygon
  1183.     lnumverts = fa->numedges;
  1184.  
  1185.     //
  1186.     // draw texture
  1187.     //
  1188.     poly = Hunk_Alloc (sizeof(glpoly_t) + (lnumverts-4) * VERTEXSIZE*sizeof(float));
  1189.     poly->next = fa->polys;
  1190.     poly->numverts = lnumverts;
  1191.     fa->polys = poly;
  1192.  
  1193.     for (i=0 ; i<lnumverts ; i++)
  1194.     {
  1195.         lindex = currentmodel->surfedges[fa->firstedge + i];
  1196.  
  1197.         if (lindex > 0)
  1198.         {
  1199.             r_pedge = ¤tmodel->edges[lindex];
  1200.             vec = currentmodel->vertexes[r_pedge->v[0]].position;
  1201.         }
  1202.         else
  1203.         {
  1204.             r_pedge = ¤tmodel->edges[-lindex];
  1205.             vec = currentmodel->vertexes[r_pedge->v[1]].position;
  1206.         }
  1207.  
  1208.         s = DotProduct (vec, fa->texinfo->vecs[0]) + fa->texinfo->vecs[0][3];
  1209.         s /= fa->texinfo->image->width;
  1210.  
  1211.         t = DotProduct (vec, fa->texinfo->vecs[1]) + fa->texinfo->vecs[1][3];
  1212.         t /= fa->texinfo->image->height;
  1213.  
  1214.         VectorCopy (vec, poly->verts[i]);
  1215.         poly->verts[i][3] = s;
  1216.         poly->verts[i][4] = t;
  1217.  
  1218.         //
  1219.         // lightmap texture coordinates
  1220.         //
  1221.         s = DotProduct (vec, fa->texinfo->vecs[0]) + fa->texinfo->vecs[0][3];
  1222.         s -= fa->texturemins[0];
  1223.         s += fa->light_s*16;
  1224.         s += 8;
  1225.         s /= BLOCK_WIDTH*16; //fa->texinfo->texture->width;
  1226.  
  1227.         t = DotProduct (vec, fa->texinfo->vecs[1]) + fa->texinfo->vecs[1][3];
  1228.         t -= fa->texturemins[1];
  1229.         t += fa->light_t*16;
  1230.         t += 8;
  1231.         t /= BLOCK_HEIGHT*16; //fa->texinfo->texture->height;
  1232.  
  1233.         poly->verts[i][5] = s;
  1234.         poly->verts[i][6] = t;
  1235.     }
  1236. }
  1237.  
  1238. /*
  1239. ========================
  1240. GL_CreateSurfaceLightmap
  1241. ========================
  1242. */
  1243. void GL_CreateSurfaceLightmap (msurface_t *surf)
  1244. {
  1245.     int        smax, tmax;
  1246.     byte    *base;
  1247.  
  1248.     if (!surf->samples)
  1249.         return;
  1250.  
  1251.     if (surf->texinfo->flags & (SURF_SKY|SURF_WARP))
  1252.         return; //may not need this?
  1253.  
  1254.     smax = (surf->extents[0]>>4)+1;
  1255.     tmax = (surf->extents[1]>>4)+1;
  1256.  
  1257.     if ( !LM_AllocBlock( smax, tmax, &surf->light_s, &surf->light_t ) )
  1258.     {
  1259.         LM_UploadBlock( false );
  1260.         LM_InitBlock();
  1261.         if ( !LM_AllocBlock( smax, tmax, &surf->light_s, &surf->light_t ) )
  1262.         {
  1263.             Com_Error( ERR_FATAL, "Consecutive calls to LM_AllocBlock(%d,%d) failed\n", smax, tmax );
  1264.         }
  1265.     }
  1266.  
  1267.     surf->lightmaptexturenum = gl_lms.current_lightmap_texture;
  1268.  
  1269.     base = gl_lms.lightmap_buffer;
  1270.     base += (surf->light_t * BLOCK_WIDTH + surf->light_s) * LIGHTMAP_BYTES;
  1271.  
  1272.     R_SetCacheState( surf );
  1273.     R_BuildLightMap (surf, base, BLOCK_WIDTH*LIGHTMAP_BYTES);
  1274. }
  1275.  
  1276. /*
  1277. ========================
  1278. GL_CreateSurfaceStainmap
  1279. ========================
  1280. */
  1281. void GL_CreateSurfaceStainmap (msurface_t *surf)
  1282. {
  1283.     int        smax, tmax;
  1284.  
  1285.     if (!surf->samples)
  1286.         return;
  1287.  
  1288.     smax = (surf->extents[0]>>4)+1;
  1289.     tmax = (surf->extents[1]>>4)+1;
  1290.  
  1291.     surf->stainsamples = Hunk_Alloc (smax*tmax*3);
  1292.     memset (surf->stainsamples, 255, smax*tmax*3);
  1293. }
  1294.  
  1295. /*
  1296. ==================
  1297. GL_BeginBuildingLightmaps
  1298.  
  1299. ==================
  1300. */
  1301. void GL_BeginBuildingLightmaps (model_t *m)
  1302. {
  1303.     static lightstyle_t    lightstyles[MAX_LIGHTSTYLES];
  1304.     int                i;
  1305.     unsigned        dummy[128*128];
  1306.  
  1307.     memset( gl_lms.allocated, 0, sizeof(gl_lms.allocated) );
  1308.  
  1309.     r_framecount = 1;        // no dlightcache
  1310.  
  1311.     GL_EnableMultitexture( true );
  1312.     GL_SelectTexture( GL_TEXTURE1);
  1313.  
  1314.     /*
  1315.     ** setup the base lightstyles so the lightmaps won't have to be regenerated
  1316.     ** the first time they're seen
  1317.     */
  1318.     for (i=0 ; i<MAX_LIGHTSTYLES ; i++)
  1319.     {
  1320.         lightstyles[i].rgb[0] = 1;
  1321.         lightstyles[i].rgb[1] = 1;
  1322.         lightstyles[i].rgb[2] = 1;
  1323.         lightstyles[i].white = 3;
  1324.     }
  1325.     r_newrefdef.lightstyles = lightstyles;
  1326.  
  1327.     if (!gl_state.lightmap_textures)
  1328.         gl_state.lightmap_textures    = TEXNUM_LIGHTMAPS;
  1329.  
  1330.     gl_lms.current_lightmap_texture = 1;
  1331.  
  1332.     /*
  1333.     ** if mono lightmaps are enabled and we want to use alpha
  1334.     ** blending (a,1-a) then we're likely running on a 3DLabs
  1335.     ** Permedia2.  In a perfect world we'd use a GL_ALPHA lightmap
  1336.     ** in order to conserve space and maximize bandwidth, however 
  1337.     ** this isn't a perfect world.
  1338.     **
  1339.     ** So we have to use alpha lightmaps, but stored in GL_RGBA format,
  1340.     ** which means we only get 1/16th the color resolution we should when
  1341.     ** using alpha lightmaps.  If we find another board that supports
  1342.     ** only alpha lightmaps but that can at least support the GL_ALPHA
  1343.     ** format then we should change this code to use real alpha maps.
  1344.     */
  1345.     if ( toupper( gl_monolightmap->string[0] ) == 'A' )
  1346.     {
  1347.         gl_lms.internal_format = gl_tex_alpha_format;
  1348.     }
  1349.     /*
  1350.     ** try to do hacked colored lighting with a blended texture
  1351.     */
  1352.     else if ( toupper( gl_monolightmap->string[0] ) == 'C' )
  1353.     {
  1354.         gl_lms.internal_format = gl_tex_alpha_format;
  1355.     }
  1356.     else if ( toupper( gl_monolightmap->string[0] ) == 'I' )
  1357.     {
  1358.         gl_lms.internal_format = GL_INTENSITY8;
  1359.     }
  1360.     else if ( toupper( gl_monolightmap->string[0] ) == 'L' ) 
  1361.     {
  1362.         gl_lms.internal_format = GL_LUMINANCE8;
  1363.     }
  1364.     else
  1365.     {
  1366.         gl_lms.internal_format = gl_tex_solid_format;
  1367.     }
  1368.  
  1369.     /*
  1370.     ** initialize the dynamic lightmap texture
  1371.     */
  1372.     GL_Bind( gl_state.lightmap_textures + 0 );
  1373.     qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  1374.     qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  1375.     qglTexImage2D( GL_TEXTURE_2D, 
  1376.                    0, 
  1377.                    gl_lms.internal_format,
  1378.                    BLOCK_WIDTH, BLOCK_HEIGHT, 
  1379.                    0, 
  1380.                    GL_LIGHTMAP_FORMAT, 
  1381.                    GL_UNSIGNED_BYTE, 
  1382.                    dummy );
  1383. }
  1384.  
  1385. /*
  1386. =======================
  1387. GL_EndBuildingLightmaps
  1388. =======================
  1389. */
  1390. void GL_EndBuildingLightmaps (void)
  1391. {
  1392.     LM_UploadBlock( false );
  1393.     GL_EnableMultitexture( false );
  1394. }
  1395.  
  1396.